/* eslint-disable no-loop-func */
/* eslint-disable max-len */
import { Ref, SetupContext } from 'vue';
import { TreeViewProps } from '../tree-view.props';
import { cloneDeep } from 'lodash';
import { VisualTreeNodeCell } from './types';

/** 用于处理树自动勾选子节点和优先返回父节点相关功能 */
export function useAutoCheckChildrenAndCascade(props: TreeViewProps, visibleDatasValue: any, dictTree: any, maxLayer: number, context: SetupContext): any {
    /** 选中值 */
    let outputValue: any;
    /** 记录选中值（选中父节点时，不自动选中子节点）*/
    const recordCheckedValues: any = [];

    /** 找出已经checked的节点 */
    function fetchCheckedNodes(currentTree: any) {
        /** 已经checked的节点 */
        let checkedGroup: any = [];
        for (let i = 1; i < currentTree.childNodes.length - 1; i++) {
            const inputOfEachNode = currentTree.childNodes[i].querySelector('input');
            if (inputOfEachNode) {
                if (inputOfEachNode.checked) {
                    checkedGroup.push(i.toString());
                    const uniqueSet = new Set(checkedGroup);
                    checkedGroup = [...uniqueSet];
                }
            }
        }
        return checkedGroup;
    }

    /** isBInA:判断B中的每个元素是否都在A中 */
    function isBInA(A: any, B: any) {
        for (let i = 0; i < B.length; i++) {
            if (!A.includes(B[i])) {
                return false;
            }
        }
        return true;
    }

    /** A-B:求差 */
    function getDifference(A: any, B: any) {
        const C = A.filter((element: any) => {
            return B.indexOf(element) === -1;
        });
        return C;
    }

    /** 修改父节点选中图标，如indeterminate图标代表部分选中情况 */
    function handleTreeNodeParentsIcon(visualTreeNodeCell: any, dictTree: any, currentTree: any) {
        let neighborParentIndex = dictTree[visualTreeNodeCell.index].neighborParentId;
        while (neighborParentIndex !== '') {
            const checkedGroup = fetchCheckedNodes(currentTree);
            const childsLeft = getDifference(dictTree[neighborParentIndex].childs, checkedGroup);
            const parentInput = currentTree.childNodes[neighborParentIndex].querySelector('input');
            // 若完全不同，则为空状态
            if (childsLeft.length === dictTree[neighborParentIndex].childs.length && childsLeft.length !== 0) {
                parentInput.indeterminate = false;
                parentInput.checked = false;
            }
            // 若完全相同，则为勾选状态
            else if (childsLeft.length === 0) {
                parentInput.indeterminate = false;
                parentInput.checked = true;
            }
            // 有重合但不完全相同，则为中间状态
            else if (childsLeft.length < dictTree[neighborParentIndex].childs.length) {
                parentInput.indeterminate = true;
                parentInput.checked = false;
            }
            neighborParentIndex = dictTree[neighborParentIndex].neighborParentId;
        }
    }
    /** 优先返回父节点 */
    function trimmedParentValue(checkedGroup: any, outputValue: any) {
        let trimmedOutputValue: any = [];
        const subset: any = [];
        for (let i = 0; i <= maxLayer; i++) {
            outputValue.forEach((item: any) => {
                if (item.layer === i && !isBInA(subset, [item.index])) {
                    const isSubset = isBInA(checkedGroup, dictTree[item.index].childs);
                    if (isSubset) {
                        trimmedOutputValue.push(item.index);
                        subset.push(...dictTree[item.index].childs);
                    } else {
                        trimmedOutputValue.push(item.index);
                    }
                }
            });
        }
        // 排序
        const uniqueSet = new Set(trimmedOutputValue);
        const outputArray = [...uniqueSet];
        trimmedOutputValue = outputArray.sort((a, b) => Number(a) - Number(b));
        return trimmedOutputValue;
    }
    /** 优先返回父节点值（cascade===true） */
    function returnParentValue(trimmedOutputValue: any) {
        outputValue = [];
        trimmedOutputValue.forEach((groupItem: any) => {
            const displayTextTmp = visibleDatasValue[groupItem - 1].data.displayText;
            const outputValueItem = {
                data: displayTextTmp.data,
                index: displayTextTmp.index,
                layer: displayTextTmp.layer,
                parentId: displayTextTmp.parentId,
                field: displayTextTmp.field,
            };
            outputValue.push(cloneDeep(outputValueItem));
        });
        return outputValue;
    }
    /** 返回父子选中值（cascade===false */
    function returnBothValue(currentTree: any) {
        const checkedGroup = fetchCheckedNodes(currentTree);
        outputValue = [];
        checkedGroup.forEach((groupItem: any) => {
            const displayTextTmp = visibleDatasValue[groupItem - 1].data.displayText;
            const outputValueItem = {
                data: displayTextTmp.data,
                index: displayTextTmp.index,
                layer: displayTextTmp.layer,
                parentId: displayTextTmp.parentId,
                field: displayTextTmp.field,
            };
            outputValue.push(cloneDeep(outputValueItem));
        });
        if (outputValue.length !== 0) {
            // 值包含父子节点值
            context.emit('outputValue', outputValue);
            if (props.cascade) {
                // cascade为true，代表值优先返回父节点的值
                const trimmedOutputValue = trimmedParentValue(checkedGroup, outputValue);
                outputValue = returnParentValue(trimmedOutputValue);
            }
            console.log(outputValue);
        }

    }
    /** 根据子节点状态，自动重置当前节点状态 */
    function resetCurrentNodeBasedOnChildsStatus(payload: any, visualTreeNodeCell: VisualTreeNodeCell) {
        const hasCommonValue = dictTree[visualTreeNodeCell.index].childs.some((child: any) => recordCheckedValues.includes(child));
        if (hasCommonValue) {
            // 处理点击的节点，获取当前的checked的attribute值
            const previousElementSiblings = payload.target.previousElementSibling;
            const checkedValue = previousElementSiblings.checked;
            if (checkedValue !== true) {
                previousElementSiblings.checked = false;
                previousElementSiblings.indeterminate = true;
            }
        }
    }
    /** 不通过父勾选子的父节点处理方法 */
    function handleTreeNodeParentsIconManually(payload: any, visualTreeNodeCell: VisualTreeNodeCell, dictTree: any, currentTree: any, recordCheckedValues: any) {
        let neighborParentIndex = dictTree[visualTreeNodeCell.index].neighborParentId;
        // 检索已经勾选的项是否为其子节点，若为子节点，则重新置为中间状态
        resetCurrentNodeBasedOnChildsStatus(payload, visualTreeNodeCell);
        while (neighborParentIndex !== '') {
            const checkedGroup = fetchCheckedNodes(currentTree);
            const childsLeft = getDifference(dictTree[neighborParentIndex].childs, checkedGroup);
            const parentInput = currentTree.childNodes[neighborParentIndex].querySelector('input');
            // 若完全不同，则为空状态
            if (childsLeft.length === dictTree[neighborParentIndex].childs.length && childsLeft.length !== 0) {
                if (parentInput.checked !== true) {
                    parentInput.indeterminate = false;
                    parentInput.checked = false;
                }
            }
            // 有重合但不完全相同，则为中间状态
            else if (childsLeft.length < dictTree[neighborParentIndex].childs.length) {
                if (parentInput.checked !== true) {
                    parentInput.indeterminate = true;
                    parentInput.checked = false;
                }
            }
            neighborParentIndex = dictTree[neighborParentIndex].neighborParentId;
        }
    }
    /** 记录选择的值 */
    function recordCheckedValue(visualTreeNodeCell: VisualTreeNodeCell) {
        // 如果b在a中，则删除b,否则加入b
        const index = recordCheckedValues.indexOf(visualTreeNodeCell.index);
        if (index !== -1) {
            recordCheckedValues.splice(index, 1);
        } else {
            recordCheckedValues.push(visualTreeNodeCell.index);
        }
        return recordCheckedValues;
    }
    /** 修改当前树节点 */
    function handleCurTreeNode(payload: any) {
        // 处理点击的节点，获取当前的checked的attribute值
        const previousElementSiblings = payload.target.previousElementSibling;
        const checkedValue = previousElementSiblings.checked;
        if (checkedValue) {
            previousElementSiblings.checked = false;
            previousElementSiblings.indeterminate = false;
        } else {
            previousElementSiblings.checked = true;
            previousElementSiblings.indeterminate = false;
        }
    }
    /** 处理子节点选中图标 */
    function handleTreeNodeChildsIcon(payload: any, visualTreeNodeCell: VisualTreeNodeCell, dictTree: any, currentTree: any) {
        const parentsAndChilds = dictTree[visualTreeNodeCell.index];
        if (currentTree.className === 'fv-tree-data') {
            parentsAndChilds.childs.map((child: number) => {
                const childInput = currentTree.childNodes[child].querySelector('input');
                if (childInput) {
                    const checkedValue = payload.target.previousElementSibling.checked;
                    if (checkedValue) {
                        // 选中->未选中
                        childInput.checked = false;
                        childInput.indeterminate = false;
                    } else {
                        // 未选中->选中
                        childInput.checked = true;
                        childInput.indeterminate = false;
                    }
                }
            });
        }
    }
    /** 处理树节点可勾选状态下的单元格点击事件 */
    function onClickTreeNodeSelectableCell(payload: any, visualTreeNode: any, visualTreeNodeCell: VisualTreeNodeCell, dictTree: any) {
        const currentTree = payload.target.parentNode.parentNode.parentNode;
        // 根据autoCheckChildren判断是否修改子节点；autoCheckChildren 不通过父勾选子
        if (props.autoCheckChildren) {
            handleTreeNodeChildsIcon(payload, visualTreeNodeCell, dictTree, currentTree);
            handleCurTreeNode(payload);
            handleTreeNodeParentsIcon(visualTreeNodeCell, dictTree, currentTree);
        } else {
            // 不通过父勾选子
            handleCurTreeNode(payload);
            const recordCheckedValues = recordCheckedValue(visualTreeNodeCell);
            handleTreeNodeParentsIconManually(payload, visualTreeNodeCell, dictTree, currentTree, recordCheckedValues);
        }
        returnBothValue(currentTree);
    }

    return { onClickTreeNodeSelectableCell };
}
